<?php

namespace app\http\middleware;


use app\common\traits\Client;
use Closure;
use think\facade\Cache;
use think\Response;

/**
 * 请求频率限制器（这个类名风门的翻译很到位）
 * Class Throttle
 * @package app\http\middleware\api
 */
class Throttle
{
    use Client;

    /**
     * 根据设备唯一码来做请求频率限制【未完成】
     * （这个地方限制的是当前应用所有route的请求频率，后期如果需要细致化指定某个具体route的限制，可以获取route，然后用hash格式来作为存储标识）
     * ex：Hash::set(TerminalCode,route,0,duration)
     * ps：不理解不要紧，要用到的时候自然就理解了
     * @param $request
     * @param Closure $next
     * @param string $frequency
     * @return Response
     * @throws \throwable
     */
    public function handle($request, Closure $next, string $frequency = '60,1'):Response
    {
        [$times,$duration] = explode(',',$frequency);
        $times = max(1,$times);//最高次数
        $duration = max(1,$duration);//计数有效时间长度，单位：m(分)
        $terminalCode = $this->getTerminalCode();//获取当前设备唯一标识，该标识也作为系统中计数统计的唯一标识
        if(!$terminalCode) {
            $code = 412;
            return json(config('code')[$code])->code($code);
        }
        $hadRequestTimes = Cache::remember($terminalCode,0,$duration*60);
        if($hadRequestTimes >= $times) {
            $code = 429;
            return json(config('code')[$code])->code($code);
        }
        Cache::inc($terminalCode);

        return $next($request);
    }
}